import json
from io import BytesIO

from django.http import HttpResponse
from django.utils.encoding import escape_uri_path
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ModelViewSet, ViewSet

from backend.utils.base_permission import CustomPermission
from backend.utils.jwt_authenticate import MyJSONWebTokenAuthentication
from backend.utils.mixins import ExportModelMixin
from backend.utils.renders import FileRender
from backend.utils.response import ApiResponse
import pandas as pd


class BaseModelViewSet(ModelViewSet):
    permission_classes = [IsAuthenticated, CustomPermission, ]
    authentication_classes = [MyJSONWebTokenAuthentication]
    white_list = []

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        _page = request.query_params.get('page')
        page_size = request.query_params.get('page_size')
        page = self.paginate_queryset(queryset)
        if page is not None and any([_page, page_size]):
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(data=serializer.data)

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return ApiResponse(data=serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        return ApiResponse(data=serializer.data)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            # If 'prefetch_related' has been applied to a queryset, we need to
            # forcibly invalidate the prefetch cache on the instance.
            instance._prefetched_objects_cache = {}

        return ApiResponse(data=serializer.data)

    def destroy(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.is_delete = True
        instance.save()
        return ApiResponse(message='删除成功', code=200, data=None)

    def get_serializer_class(self):
        if isinstance(self.serializer_class, dict):
            return self.serializer_class.get(self.action) or self.serializer_class.get('default')

        return self.serializer_class

    def check_permissions(self, request):
        if self.action in self.white_list:
            return True
        return super().check_permissions(request)


class ExportableViewSet(BaseModelViewSet, ExportModelMixin):
    pass
